package com.easybbs.utils;

import com.easybbs.entity.config.AppConfig;
import com.easybbs.entity.constants.Constants;
import com.easybbs.entity.dto.FileUploadDto;
import com.easybbs.entity.enums.DateTimePatternEnum;
import com.easybbs.entity.enums.FileUploadTypeEnum;
import com.easybbs.exception.BusinessException;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Date;

/**
 * 文件图片上传工具类
 */
@Component
public class FileUtils {
    private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);
    @Autowired
    private AppConfig appConfig;

    @Autowired
    private ImageUtils imageUtils;

    /**
     * 评论(头像、封面)上传发送图片
     *
     * @param file
     * @param folder
     * @param uploadTypeEnum
     * @return
     */
    public FileUploadDto uploadFile2Local(MultipartFile file, String folder, FileUploadTypeEnum uploadTypeEnum) {
        try {
            FileUploadDto uploadDto = new FileUploadDto();
            String originalFilename = file.getOriginalFilename();
            String fileSuffix = StringTools.getFileSuffix(originalFilename);
            if (originalFilename.length() > Constants.LENGTH_200) {
                //名字太长进行一个处理
                originalFilename = StringTools.getFileName(originalFilename).substring(0, Constants.LENGTH_200) + fileSuffix;
            }
            //检查传递的文件图片类型是否合格
            if (!ArrayUtils.contains(uploadTypeEnum.getSuffixArray(), fileSuffix)) {
                throw new BusinessException("文件格式不正确");
            }

            //图片以年月来区分
            String month = DateUtil.format(new Date(), DateTimePatternEnum.YYYYMM.getPattern());
            //基本文件路径：当前项目文件/file/
            String baseFolder = appConfig.getProjectFolder() + Constants.FILE_FOLDER_FILE;
            //目标文件夹路径
            File targetFileFolder = new File(baseFolder + folder + month + "/");

            //上传服务器目标的真实文件名
            String fileName = StringTools.getRandomString(Constants.LENGTH_15) + fileSuffix;

            //目标文件路径
            File tragetFile = new File(targetFileFolder.getPath() + "/" + fileName);
            //月份加真实文件名生成的路径
            String localPath = month + "/" + fileName;

            if (uploadTypeEnum == FileUploadTypeEnum.AVATAR) {
                //TODO 头像上传
                targetFileFolder = new File(baseFolder + Constants.FILE_FOLDER_AVATAR_NAME);
                tragetFile = new File(targetFileFolder.getPath() + "/" + folder + Constants.AVATAR_SUFFIX);
                localPath = folder + Constants.AVATAR_SUFFIX;
            }

            //判断目标文件夹是否存在，不存在则创建
            if (!targetFileFolder.exists()) {
                targetFileFolder.mkdirs();
            }

            // 将上传的文件保存到目标文件
            file.transferTo(tragetFile);

            //压缩图片
            if (uploadTypeEnum == FileUploadTypeEnum.COMMENT_IMAGE) {
                //缩略图 将缩略图文件名后缀变成 _.
                String thumbnailName = tragetFile.getName().replace(".", "_.");
                //缩略图路径
                File thumbnail = new File(tragetFile.getParent() + "/" + thumbnailName);
                Boolean thumbnailCreate = imageUtils.createThumbnail(tragetFile, Constants.LENGTH_200, Constants.LENGTH_200, thumbnail);
                //没有缩略图的时候生成
                if (!thumbnailCreate) {
                    //将原图复制到缩略图 俩份
                    org.apache.commons.io.FileUtils.copyFile(tragetFile, thumbnail);
                }
            } else if (uploadTypeEnum == FileUploadTypeEnum.AVATAR || uploadTypeEnum == FileUploadTypeEnum.ARTICLE_COVER) {
                //头像和文章封面，将图片压缩到200*200
                imageUtils.createThumbnail(tragetFile, Constants.LENGTH_200, Constants.LENGTH_200, tragetFile);
            }
            uploadDto.setLocalPath(localPath);
            uploadDto.setOriginalFilename(originalFilename);
            return uploadDto;
        } catch (BusinessException e) {
            logger.error("文件上传失败", e);
            throw e;
        } catch (Exception e) {
            logger.error("文件上传失败", e);
            throw new BusinessException("文件上传失败");
        }
    }
}
